home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char SccsId[]= "@(#)modelfuns.c V1.13 3/17/95";
- #endif
-
- /* modelfuns.c */
-
- #include "std.h"
- #include "dvstd.h"
- #include "dvtools.h"
- #include "VUfundecl.h"
- #include "VGfundecl.h"
- #include "prc_fundecl.h"
-
- #ifndef WINNT
- #include <time.h>
- #endif /* WINNT */
-
-
- /* model "constants" */
- LOCAL FLOAT STGCAP = 100;
- LOCAL FLOAT RVCAP = 1000;
- LOCAL FLOAT STMTMP = 200;
- LOCAL FLOAT STMDELTA = 50;
- LOCAL FLOAT OUTTMP = 70;
- LOCAL FLOAT STMTRAN = .1F;
- LOCAL FLOAT PIPEVOL = 2;
- LOCAL FLOAT ITERLEN = 2;
- LOCAL FLOAT VALVEINCR = 0.2F;
- LOCAL FLOAT STM_CTL_PARAM = 5;
- LOCAL FLOAT INTMPMIN = 0.33F;
- LOCAL FLOAT INFLOWMIN = 0.33F;
- LOCAL FLOAT OUT_TOLER = 0.1F;
- LOCAL FLOAT VALVESTICKINESS = 0.05F;
- LOCAL FLOAT UNSTICKINESS = 0.3F;
-
- typedef struct
- {
- ULONG time, itercount;
- FLOAT hour, minute, second;
- FLOAT in_tmp, in_flow, stg_tmp, stg_vol, stg_of_vol, rv_tmp, rv_vol, wst_vol, out_vol, tot_tmp_err, in_valve, stg_valve, stm_valve, out_valve, wst_valve, stuck_in_valve, stuck_stg_valve, stuck_stm_valve, stuck_out_valve, stuck_wst_valve, stm_tmp, stg_of_flow, stg_out_flow, rv_of_flow, wst_flow, out_flow, avg_tmp_err, cur_tmp_err, pct_tot_wst, avg_tmp_good, cur_tmp_good, pct_wst_good, raw_flow[50], produce_flow[50];
- } MODELVARS;
-
- LOCAL MODELVARS current, last; /* current and last values */
- LOCAL FLOAT total_input = 0;
- LOCAL FLOAT total_wst_n_of = 0;
-
- LOCAL DV_BOOL inited_once = NO;
-
- /***************** Begin Function Declarations *************/
- LOCAL double rand01 V_P_((void));
- LOCAL void fmod01 V_P_((float *f, double modulus));
- LOCAL void getinputs V_P_((void));
- LOCAL double make_100_goodness V_P_((double badness, double maximum_bad));
- LOCAL void getmodelvars V_P_((void));
- LOCAL void changevalve V_P_((float *valve_ptr, int delta));
- LOCAL void unsticktry2 V_P_((float *stuckness_ptr, float *valve_ptr, int delta));
- LOCAL void tryvalve2 V_P_((float *stuckness_ptr, float *valve_ptr, int delta));
- /***************** End Function Declarations *************/
-
- void MDLinit
- V_P_ ((void))
- {
- INT i;
- FILE *const_file;
-
- current.time = 0;
- current.itercount = 0;
- current.in_tmp = 0.0;
- current.in_flow = 0.0;
- current.stg_vol = 0.0;
- current.stg_tmp = 0.0;
- current.stg_of_vol = 0.0;
- current.rv_vol = 0.0;
- current.rv_tmp = 0.0;
- current.stm_tmp = 0.0;
- current.wst_vol = 0.0;
- current.out_vol = 0.0;
- current.tot_tmp_err = 0.0;
- current.in_valve = 0.0;
- current.stg_valve = 0.0;
- current.stm_valve = 0.0;
- current.wst_valve = 0.0;
- current.out_valve = 0.0;
- current.stg_of_flow = 0.0;
- current.stg_out_flow = 0.0;
- current.rv_of_flow = 0.0;
- current.wst_flow = 0.0;
- current.out_flow = 0.0;
- current.avg_tmp_err = 0.0;
- current.cur_tmp_err = 0.0;
- current.pct_tot_wst = 0.0;
- current.avg_tmp_good = 0.0;
- current.cur_tmp_good = 0.0;
- current.pct_wst_good = 0.0;
-
- for (i = 0; i < 50; i++)
- {
- current.raw_flow[i] = 0.0;
- current.produce_flow[i] = 0.0;
- }
-
- total_input = 0;
- total_wst_n_of = 0;
-
- memcpy(&last, ¤t, sizeof (MODELVARS));
-
- if (!inited_once)
- {
- VUsrand (time (0));
-
- if ((const_file = (FILE *) S_FOPEN ("model.consts", "r")) == 0)
-
- printf ("Couldn't open 'modelast.consts'. Using default values.\n");
- else
- {
- fscanf (const_file, "%f%*s\n%f%*s\n%f%*s\n%f%*s\n%f%*s\n",
- &STGCAP, &RVCAP, &STMTMP, &STMDELTA, &OUTTMP);
- fscanf (const_file, "%f%*s\n%f%*s\n%f%*s\n%f%*s\n%f%*s\n",
- &STMTRAN, &PIPEVOL, &ITERLEN, &VALVEINCR, &STM_CTL_PARAM);
- fscanf (const_file, "%f%*s\n%f%*s\n%f%*s\n%f%*s\n%f%*s\n",
- &INTMPMIN, &INFLOWMIN, &OUT_TOLER,
- &VALVESTICKINESS, &UNSTICKINESS);
- }
-
- inited_once = YES;
- }
- }
-
-
- LOCAL double rand01
- V_P_ ((void))
- {
- return VUfrand ();
- }
-
-
- LOCAL void
- fmod01 (f, modulus)
- float *f;
- double modulus;
- {
- while (*f >= modulus)
- *f = (FLOAT)(*f - modulus);
- }
-
-
- void MDLupdate
- V_P_ ((void))
- {
- current.itercount++;
- getinputs ();
- getmodelvars ();
- memcpy(&last, ¤t, sizeof (MODELVARS));
- }
-
-
- LOCAL FLOAT raw_flow_offset = 0;
-
-
- LOCAL void getinputs
- V_P_ ((void))
- {
- INT i, flowoffset;
-
- if (current.in_valve != 0.0)
- {
- current.in_tmp = (FLOAT)(OUTTMP * (INTMPMIN + (1 - INTMPMIN) * rand01 ()));
- current.in_flow =
- (FLOAT)(current.in_valve * PIPEVOL * (INFLOWMIN + (1 - INFLOWMIN) * rand01 ()));
- }
- else
- current.in_flow = 0.0; /* temp constant if valve closed */
-
- if (current.in_flow > 0.0)
- {
- raw_flow_offset += current.in_flow * 3;
- fmod01 (&raw_flow_offset, 13.0);
- flowoffset = (INT)raw_flow_offset;
- for (i = 0; i < 50; i++)
- {
- if ((i % 13) == flowoffset)
- current.raw_flow[i] = STMTMP;
- else
- current.raw_flow[i] = last.stg_tmp;
- }
- }
- }
-
-
- LOCAL double
- make_100_goodness (badness, maximum_bad)
- double badness;
- double maximum_bad;
- {
- return 100.0 * (maximum_bad - badness) / maximum_bad;
- }
-
-
- LOCAL FLOAT produce_flow_offset = 0;
-
-
- LOCAL void getmodelvars
- V_P_ ((void))
- {
- INT i, flowoffset;
-
- /* 1st compute intermediates and outputs from valve settings etc*/
- current.stm_tmp = current.stm_tmp + STM_CTL_PARAM *
- (current.stm_valve * STMTMP - current.stm_tmp);
- current.stm_tmp = S_MIN (STMTMP, current.stm_tmp);
- current.out_flow = S_MAX (0.0F,
- S_MIN (last.rv_vol,
- current.out_valve * PIPEVOL * 0.5F *
- (1 + last.rv_vol / RVCAP)));
- if (current.out_flow > 0.0)
- {
- produce_flow_offset += current.out_flow * 3;
- fmod01 (&produce_flow_offset, 13.0);
- flowoffset = (INT)produce_flow_offset;
- for (i = 0; i < 50; i++)
- {
- if ((i % 13) == flowoffset)
- current.produce_flow[i] = STMTMP;
- else
- current.produce_flow[i] = last.rv_tmp;
- }
- }
-
- current.wst_flow = S_MAX (0.0F,
- S_MIN (last.rv_vol - last.out_flow,
- current.wst_valve * PIPEVOL * 0.5F *
- (1 + last.rv_vol / RVCAP)));
- current.stg_out_flow = S_MAX (0.0F,
- S_MIN (last.stg_vol,
- current.stg_valve * PIPEVOL * 0.5F *
- (1 + last.stg_vol / STGCAP)));
- current.cur_tmp_err = DV_VIABS (OUTTMP - last.rv_tmp) /
- (3.0F * OUT_TOLER * OUTTMP);
- current.cur_tmp_good = (FLOAT)make_100_goodness (
- (0.5F + 0.5F * current.cur_tmp_err) *
- (0.5F + 0.5F * (1.0F - current.out_valve)) - 0.25F,
- 1.0F);
- current.tot_tmp_err = last.tot_tmp_err + current.cur_tmp_err;
- current.avg_tmp_err = current.tot_tmp_err / current.itercount;
- current.avg_tmp_good = (FLOAT)make_100_goodness (current.avg_tmp_err, 1.0F);
-
- /* now compute state vars */
- current.stg_vol = S_MAX (0.0F,
- last.stg_vol - current.stg_out_flow + current.in_flow);
- current.stg_of_flow = S_MAX (0.0F, current.stg_vol - STGCAP);
- current.stg_vol = S_MIN (STGCAP, current.stg_vol);
- current.stg_of_vol = last.stg_of_vol + current.stg_of_flow;
-
- if (current.stg_vol > 0.0)
- current.stg_tmp = 0.98F * last.stg_tmp +
- ((last.in_tmp - last.stg_tmp) * current.in_flow) /
- (last.stg_vol + 1);
- else
- current.stg_tmp = 0.0;
-
- current.rv_vol = S_MAX (0.0F, last.rv_vol + current.stg_out_flow -
- (current.out_flow + current.wst_flow));
- current.rv_of_flow = S_MAX (0.0F, current.rv_vol - RVCAP);
- current.rv_vol = S_MIN (RVCAP, current.rv_vol);
-
- if (current.rv_vol > RVCAP * 0.05)
- {
- current.rv_tmp = 0.995F * last.rv_tmp +
- ((last.stg_tmp - last.rv_tmp) * last.stg_out_flow +
- (last.stm_tmp - last.rv_tmp) * STMTRAN) /
- (last.rv_vol + 1);
- current.rv_tmp = S_MAX (0.0F, current.rv_tmp);
- }
- else if (current.rv_vol > 0.0)
- {
- current.rv_tmp = 0.995F * last.rv_tmp +
- ((last.stg_tmp - last.rv_tmp) * last.stg_out_flow +
- (last.stm_tmp - last.rv_tmp) * STMTRAN * 0.2F) /
- (last.rv_vol + 1);
- current.rv_tmp = S_MAX (0.0F, current.rv_tmp);
- }
- else
- current.rv_tmp = 0.0;
-
- current.wst_vol = last.wst_vol + current.wst_flow + current.rv_of_flow;
- current.out_vol = last.out_vol + current.out_flow;
- total_input = total_input + current.in_flow;
- total_wst_n_of = total_wst_n_of + current.wst_flow +
- current.stg_of_flow + current.rv_of_flow;
- current.pct_tot_wst = total_wst_n_of / (total_input + 0.01F);
- current.pct_wst_good = (FLOAT)make_100_goodness (current.pct_tot_wst, 1.0F);
- }
-
-
- LOCAL void
- changevalve (valve_ptr, delta)
- float *valve_ptr;
- int delta;
- {
- if (delta > 0)
- *valve_ptr = S_MIN (1.0F, *valve_ptr + VALVEINCR);
- else
- *valve_ptr = S_MAX (0.0F, *valve_ptr - VALVEINCR);
- }
-
-
- LOCAL void
- unsticktry2 (stuckness_ptr, valve_ptr, delta)
- float *stuckness_ptr;
- float *valve_ptr;
- int delta;
- {
- if (rand01 ()< UNSTICKINESS)
- *stuckness_ptr = 0;
- }
-
-
- LOCAL void
- tryvalve2 (stuckness_ptr, valve_ptr, delta)
- float *stuckness_ptr;
- float *valve_ptr;
- int delta;
- {
- if (rand01 ()< VALVESTICKINESS)
- *stuckness_ptr = 1;
- else
- changevalve (valve_ptr, delta);
- }
-
-
- void
- MDLchangevalve (valve_name, delta)
- char *valve_name;
- int delta;
- {
- if ((strcmp (valve_name, "valve_out") == 0) ||
- (strcmp (valve_name, "valve_out_stuck") == 0))
- if (current.stuck_out_valve == 0)
- tryvalve2 (¤t.stuck_out_valve, ¤t.out_valve, delta);
- else
- unsticktry2 (¤t.stuck_out_valve, ¤t.out_valve, delta);
- else if ((strcmp (valve_name, "valve_stm") == 0) ||
- (strcmp (valve_name, "valve_stm_stuck") == 0))
- if (current.stuck_stm_valve == 0)
- tryvalve2 (¤t.stuck_stm_valve, ¤t.stm_valve, delta);
- else
- unsticktry2 (¤t.stuck_stm_valve, ¤t.stm_valve, delta);
- else if ((strcmp (valve_name, "valve_stg") == 0) ||
- (strcmp (valve_name, "valve_stg_stuck") == 0))
- if (current.stuck_stg_valve == 0)
- tryvalve2 (¤t.stuck_stg_valve, ¤t.stg_valve, delta);
- else
- unsticktry2 (¤t.stuck_stg_valve, ¤t.stg_valve, delta);
- else if ((strcmp (valve_name, "valve_in") == 0) ||
- (strcmp (valve_name, "valve_in_stuck") == 0))
- if (current.stuck_in_valve == 0)
- tryvalve2 (¤t.stuck_in_valve, ¤t.in_valve, delta);
- else
- unsticktry2 (¤t.stuck_in_valve, ¤t.in_valve, delta);
- }
-
-
- ADDRESS
- MDLget_buffer (vdp)
- ADDRESS vdp;
- {
- CHAR *var_name;
-
- var_name = VGvdvarname (vdp);
-
- if (strcmp (var_name, "raw_flow") == 0)
- return (ADDRESS) & current.raw_flow[0];
- if (strcmp (var_name, "produce_flow") == 0)
- return (ADDRESS) & current.produce_flow[0];
-
- if (strcmp (var_name, "raw_material") == 0)
- return (ADDRESS) & current.in_flow;
- if (strcmp (var_name, "input_valve") == 0)
- return (ADDRESS) & current.in_valve;
- if (strcmp (var_name, "hold_tmp_vol") == 0)
- return (ADDRESS) & current.stg_tmp;
- if (strcmp (var_name, "holding_overflow") == 0)
- return (ADDRESS) & current.stg_of_flow;
- if (strcmp (var_name, "inter_valve") == 0)
- return (ADDRESS) & current.stg_valve;
- if (strcmp (var_name, "steam_valve") == 0)
- return (ADDRESS) & current.stm_valve;
- if (strcmp (var_name, "steam_temp") == 0)
- return (ADDRESS) & current.stm_tmp;
- if (strcmp (var_name, "reac_tmp_vol") == 0)
- return (ADDRESS) & current.rv_tmp;
- if (strcmp (var_name, "reaction_overflow") == 0)
- return (ADDRESS) & current.rv_of_flow;
- if (strcmp (var_name, "output_valve") == 0)
- return (ADDRESS) & current.out_valve;
- if (strcmp (var_name, "produce") == 0)
- return (ADDRESS) & current.out_flow;
- if (strcmp (var_name, "stuck_input_valve") == 0)
- return (ADDRESS) & current.stuck_in_valve;
- if (strcmp (var_name, "stuck_inter_valve") == 0)
- return (ADDRESS) & current.stuck_stg_valve;
- if (strcmp (var_name, "stuck_steam_valve") == 0)
- return (ADDRESS) & current.stuck_stm_valve;
- if (strcmp (var_name, "stuck_output_valve") == 0)
- return (ADDRESS) & current.stuck_out_valve;
- if (strcmp (var_name, "inter_flow") == 0)
- return (ADDRESS) & current.stg_out_flow;
- if (strcmp (var_name, "holding_temp") == 0)
- return (ADDRESS) & current.stg_tmp;
- if (strcmp (var_name, "holding_volume") == 0)
- return (ADDRESS) & current.stg_vol;
- if (strcmp (var_name, "reaction_temp") == 0)
- return (ADDRESS) & current.rv_tmp;
- if (strcmp (var_name, "reaction_volume") == 0)
- return (ADDRESS) & current.rv_vol;
-
- return NULL;
- }
-